package com.yanfei.zero.infrastructure.config;


import java.util.UUID;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.alibaba.cola.statemachine.Action;
import com.alibaba.cola.statemachine.Condition;
import com.alibaba.cola.statemachine.StateMachine;
import com.alibaba.cola.statemachine.builder.StateMachineBuilder;
import com.alibaba.cola.statemachine.builder.StateMachineBuilderFactory;
import com.yanfei.zero.domain.user.model.User1;
import com.yanfei.zero.domain.user.repository.User1Mapper;
import com.yanfei.zero.infrastructure.config.ColaStatemachineConfig.User1State;

import cn.hutool.json.JSONUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;

/**
 * @description: 状态机配置
 * @author：lrk
 * @date: 2023/9/15
 */
@Configuration
@Slf4j
public class ColaStatemachineConfig {
	@Resource  
    private User1Mapper user1Mapper;  
	
	public enum User1State {
		INIT,
		WAIT_PAYMENT,
		WAIT_DELIVER,
		PART_DELIVERY,
		WAIT_RECEIVE,
		FINISH,
		CANCEL,
	   	REFUNDED;
	}
	// 订单事件（Events）
	public enum User1Event {
		CREATE_SUCCESS,
		PAY_SUCCESS,
		CANCEL_ORDER,
		DELIVERY_PART,
		DELIVERY_ALL,
		DELIVERED_SUCCESS,
		RECEIVED_SUCCESS,
		REFUND_SUCCESS;
	}
    @Bean
    public StateMachine<User1State, User1Event, User1> orderStateMachine() {
        String ORDER_STATE_MACHINE = "orderStateMachine"+UUID.randomUUID().toString();
        // 第一步：生成一个状态机builder
        StateMachineBuilder<User1State, User1Event, User1> builder = StateMachineBuilderFactory.create();
        
        // 第二步：定义状态
        
        // 创建订单: 初始化 -> 待支付- 创建订单
        builder.externalTransition().from(User1State.INIT).to(User1State.WAIT_PAYMENT)
        .on(User1Event.CREATE_SUCCESS)
        .when(context ->context.getStatus().equals(User1State.INIT.toString()))
        .perform((from, to, event, context) -> {
        	context.setStatus(to.toString());
        	context.setName("小明" + UUID.randomUUID());
        	user1Mapper.insert(context);
        });
        

        // 待支付状态->待发货状态 —— 支付
        //  部分发货
        builder.internalTransition()
        .within(User1State.PART_DELIVERY)
        .on(User1Event.DELIVERY_PART)
        .when(context ->context.getStatus().equals(User1State.PART_DELIVERY.toString()) )
        .perform((from, to, event, context) -> {
        	// 发起支付请求
        	
        	
        });
        
        // 取消订单: 待支付、待发货、待收货 -> 待支付
        builder.externalTransitions()
        .fromAmong(User1State.WAIT_PAYMENT,User1State.WAIT_DELIVER,User1State.WAIT_RECEIVE)
        .to(User1State.CANCEL)
        .on(User1Event.CANCEL_ORDER)
        .when(checkCondition())
        .perform((from, to, event, context) -> {
        	// 1 释放库存
        	// 2 如果已经支付 未发货 退款
        	// 3 如果已经支付 已经发货 经过商家审核
        });
        
        // 付款: 待支付 -> 待发货- 支付
        builder.externalTransition() // 外部流转
                .from(User1State.WAIT_PAYMENT)  // 起始状态
                .to(User1State.WAIT_DELIVER)  // 目标状态
                .on(User1Event.PAY_SUCCESS)  // 事件
                .when(checkCondition()) // 流转需要校验的条件，校验不通过不会进行doAction
                .perform(doAction());  //执行流转操作 这个action 我们可以按自己所需修改

        // 待发货状态->待收货状态 —— 发货
        builder.externalTransition()
                .from(User1State.WAIT_DELIVER)
                .to(User1State.WAIT_RECEIVE)
                .on(User1Event.DELIVERED_SUCCESS)
                .when(checkCondition())
                .perform(doAction());

        // 待收货状态-> 完成 —— 收货
        builder.externalTransition()
                .from(User1State.WAIT_RECEIVE)
                .to(User1State.FINISH)
                .on(User1Event.RECEIVED_SUCCESS)
                .when(checkCondition())
                .perform(doAction());
        // 创建状态机
        StateMachine<User1State, User1Event, User1> orderStateMachine = builder.build(ORDER_STATE_MACHINE);
        String uml = orderStateMachine.generatePlantUML();
        log.info("{}", uml);
        return orderStateMachine;
    }
	
    
    private Condition<User1> checkCondition() {
        return (ctx) -> {
            log.info("checkCondition:{}", JSONUtil.toJsonStr(ctx));
            return true;
        };
    }

    private Action<User1State, User1Event, User1> doAction() {
        return (from, to, event, order) -> {
            log.info(" 正在操作 " + order.getId() + " from:" + from + " to:" + to + " on:" + event);
            // 获取当前订单状态
            // 校验状态是否合法
            if (!order.getStatus().equals(from.toString())) {
            	System.out.println("状态不合法");
            }
        };
    }
}
